From 65ea6f87365b66e9a5de4a38aec9abed33fe938e Mon Sep 17 00:00:00 2001 From: =?utf8?q?=D0=A0=D1=83=D1=81=D0=BB=D0=B0=D0=BD=20=D0=98=D0=B6=D0=B1?= =?utf8?q?=D1=83=D0=BB=D0=B0=D1=82=D0=BE=D0=B2?= Date: Wed, 9 Mar 2016 09:50:09 +0000 Subject: [PATCH] GDK W32: Partially rollback the custom resize for GL windows If a window is being drawn by OpenGL, we need to apply any pending resizes to it *before* we paint. https://bugzilla.gnome.org/show_bug.cgi?id=763287 --- gdk/win32/gdkwindow-win32.c | 117 +++++++++++++++++++++++++++--------- 1 file changed, 90 insertions(+), 27 deletions(-) diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c index 847d878341..a219999f5f 100644 --- a/gdk/win32/gdkwindow-win32.c +++ b/gdk/win32/gdkwindow-win32.c @@ -195,12 +195,88 @@ gdk_window_impl_win32_finalize (GObject *object) G_OBJECT_CLASS (parent_class)->finalize (object); } +static void +gdk_win32_window_get_queued_window_rect (GdkWindow *window, + RECT *return_window_rect) +{ + gint x, y; + RECT window_rect; + + gdk_window_get_position (window, &x, &y); + window_rect.left = x; + window_rect.top = y; + window_rect.right = window_rect.left + gdk_window_get_width (window); + window_rect.bottom = window_rect.top + gdk_window_get_height (window); + + /* Turn client area into window area */ + _gdk_win32_adjust_client_rect (window, &window_rect); + + /* Convert GDK screen coordinates to W32 desktop coordinates */ + window_rect.left -= _gdk_offset_x; + window_rect.right -= _gdk_offset_x; + window_rect.top -= _gdk_offset_y; + window_rect.bottom -= _gdk_offset_y; + + *return_window_rect = window_rect; +} + +static void +gdk_win32_window_apply_queued_move_resize (GdkWindow *window, + RECT window_rect) +{ + GDK_NOTE (EVENTS, g_print ("Setting window position ... ")); + + API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), + SWP_NOZORDER_SPECIFIED, + window_rect.left, window_rect.top, + window_rect.right - window_rect.left, + window_rect.bottom - window_rect.top, + SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOREDRAW)); + + GDK_NOTE (EVENTS, g_print (" ... set window position\n")); +} + static gboolean gdk_win32_window_begin_paint (GdkWindow *window) { - GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl); + GdkWindowImplWin32 *impl; + RECT window_rect; + + if (window == NULL || GDK_WINDOW_DESTROYED (window)) + return TRUE; + + impl = GDK_WINDOW_IMPL_WIN32 (window->impl); - return !impl->layered; + /* Layered windows are moved *after* repaint. + * We supply our own surface, return FALSE to make GDK use it. + */ + if (impl->layered) + return FALSE; + + /* Non-GL windows are moved *after* repaint. + * We don't supply our own surface, return TRUE to make GDK create + * one by itself. + */ + if (!window->current_paint.use_gl) + return TRUE; + + /* GL windows are moved *before* repaint (otherwise + * repainting doesn't work), but if there's no move queued up, + * return immediately. Doesn't matter what we return, GDK + * will create a surface anyway, as if we returned TRUE. + */ + if (!impl->drag_move_resize_context.native_move_resize_pending) + return TRUE; + + impl->drag_move_resize_context.native_move_resize_pending = FALSE; + + /* Get the position/size of the window that GDK wants, + * apply it. + */ + gdk_win32_window_get_queued_window_rect (window, &window_rect); + gdk_win32_window_apply_queued_move_resize (window, window_rect); + + return TRUE; } static void @@ -208,7 +284,6 @@ gdk_win32_window_end_paint (GdkWindow *window) { GdkWindowImplWin32 *impl; RECT window_rect; - gint x, y; HDC hdc; POINT window_position; SIZE window_size; @@ -221,37 +296,25 @@ gdk_win32_window_end_paint (GdkWindow *window) impl = GDK_WINDOW_IMPL_WIN32 (window->impl); - if (!impl->layered && !impl->drag_move_resize_context.native_move_resize_pending) + /* GL windows are moved *before* repaint */ + if (window->current_paint.use_gl) return; - impl->drag_move_resize_context.native_move_resize_pending = FALSE; + /* No move/resize is queued up, and we don't need to update + * the contents of a layered window, so return immediately. + */ + if (!impl->layered && + !impl->drag_move_resize_context.native_move_resize_pending) + return; - gdk_window_get_position (window, &x, &y); - window_rect.left = x; - window_rect.top = y; - window_rect.right = window_rect.left + gdk_window_get_width (window); - window_rect.bottom = window_rect.top + gdk_window_get_height (window); + impl->drag_move_resize_context.native_move_resize_pending = FALSE; - /* Turn client area into window area */ - _gdk_win32_adjust_client_rect (window, &window_rect); + /* Get the position/size of the window that GDK wants. */ + gdk_win32_window_get_queued_window_rect (window, &window_rect); - /* Convert GDK screen coordinates to W32 desktop coordinates */ - window_rect.left -= _gdk_offset_x; - window_rect.right -= _gdk_offset_x; - window_rect.top -= _gdk_offset_y; - window_rect.bottom -= _gdk_offset_y; if (!impl->layered) { - GDK_NOTE (EVENTS, g_print ("Setting window position ... ")); - - API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), - SWP_NOZORDER_SPECIFIED, - window_rect.left, window_rect.top, - window_rect.right - window_rect.left, - window_rect.bottom - window_rect.top, - SWP_NOACTIVATE | SWP_NOZORDER)); - - GDK_NOTE (EVENTS, g_print (" ... set window position\n")); + gdk_win32_window_apply_queued_move_resize (window, window_rect); return; } -- 2.30.2